package cn.thoughtworks.school.visualization.service;

import cn.thoughtworks.school.visualization.Constant;
import cn.thoughtworks.school.visualization.entity.CacheReport;
import cn.thoughtworks.school.visualization.entity.Query;
import cn.thoughtworks.school.visualization.feign.RedashCenterFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;

import static cn.thoughtworks.school.visualization.configuration.EncacheConfig.REPORT_CACHE;

@Service
public class RedashService {
    @Autowired
    private RedashCenterFeign redashCenterFeign;
    private List init = new ArrayList();

    public Map creteQuery(String type, String sql) {
        Map map = new HashMap();
        map.put("data_source_id", 2);
        map.put("name", type);
        map.put("query", sql);
        return redashCenterFeign.createQuery(map, Constant.API_KEY);
    }

    public CacheReport findQueryResult(Query query, Long programId, Long tutorId, String type) {
        CacheReport inCache = foundInCache(type, programId, tutorId);
        if (Objects.nonNull(inCache)) {
            return inCache;
        }

        return queryResult(query, programId, tutorId, type);
    }

    public CacheReport queryResult(Query query, Long programId, Long tutorId, String type) {
        Map data = new HashMap();
        data.put("data_source_id", 2);
        data.put("max_age", 0);
        data.put("query", query.getQuery());
        data.put("query_id", query.getQueryId());
        Map<String, Map> results = redashCenterFeign.findQueryResults(data, Constant.API_KEY);
        Map<String, Map> job = new HashMap();
        int status = 0;
        while (status < 3) {
            job = redashCenterFeign.findJobsById(String.valueOf(results.get("job").get("id")), Constant.API_KEY);
            if (Objects.nonNull(job.get("job").get("status"))) {
                status = Integer.parseInt(String.valueOf(job.get("job").get("status")));
            }
        }
        Map queryResult = redashCenterFeign.findQueryResultsById(Integer.parseInt(String.valueOf(job.get("job").get("query_result_id"))), Constant.API_KEY);
        List result = format(queryResult);
        putToCache(result, programId, tutorId, type);
        return foundInCache(type,programId, tutorId);
    }

    private CacheReport foundInCache(String type, Long programId, Long tutorId) {
        return getCacheReports().stream()
            .filter(item -> item.getKey().equals(type) &&
                item.getProgramId().equals(programId)
                && item.getTutorId().equals(tutorId)).findFirst().orElse(null);
    }

    @Cacheable(cacheNames=REPORT_CACHE)
    public List<CacheReport> getCacheReports() {
        return init;
    }

    @CachePut(cacheNames=REPORT_CACHE)
    public List<CacheReport> putToCache(List data,Long programId,Long tutorId,String type) {
        List<CacheReport> cacheReports = getCacheReports();
        CacheReport cacheReport = foundInCache(type, programId, tutorId);
        if (Objects.isNull(cacheReport)) {
            cacheReports.add(CacheReport.build(data,programId,tutorId,type));
            return cacheReports;
        }
        cacheReport.update(data);
        return cacheReports;
    }

    private List format(Map result) {
        return (List) ((Map) ((Map) result.get("query_result")).get("data")).get("rows");
    }
}
